﻿using Aliphant.Mvvm.XEvent.Events;
using Aliphant.Mvvm.XEvent.Events.Base.SubScription;
using Aliphant.Mvvm.XEvent.UI;

using CommonLibrary.Helper;

using CuteWallpaperDemo.Managers;
using CuteWallpaperDemo.Models;

using DataModel;
using DataModel.Contants;
using DataModel.Models;

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using System.Windows.Input;
using System.Windows.Shapes;

namespace CuteWallpaperDemo.ViewModels
{
    public class NewMainWindowViewModel : BindableBase
    {
        private ProjectAgent _projectAgent;
        private WindowEvent _windowEvent;

        private readonly List<SubScriptionToken> _subscriptionTokens = [];

        private readonly Timer timer = new();
        private readonly object locker = new();
        private int wp_index = 0;

        public NewMainWindowViewModel()
        {
            _settings = ConfigManager.Instance.Settings;
            _projectAgent = ProjectContainer.ProjectAgent;
            _windowEvent = _projectAgent.EventManager.GetEvent<WindowEvent>();

            InitTimer();
            RegistSubScriptionToken();
            LoadWallpapers();
            ScanPlaylistCache();
        }

        /// <summary>
        /// 壁纸列表
        /// </summary>
        public ObservableCollection<string> PictureCollection { get; private set; } = [];

        /// <summary>
        /// 播放列表
        /// </summary>
        public ObservableCollection<string> PlayListCollection { get; private set; } = [];


        private Loading _loading = new Loading();
        public Loading Loading { get => _loading; set => SetProperty(ref _loading, value); }

        private bool _isPlay;
        public bool IsPlay { get => _isPlay; set => SetProperty(ref _isPlay, value); }

        private bool _playlistOpen;
        public bool PlaylistOpen { get => _playlistOpen; set => SetProperty(ref _playlistOpen, value); }

        /// <summary>
        /// 系统设置
        /// </summary>
        private SettingConfig _settings;
        public SettingConfig Settings
        {
            get => _settings;
            set
            {
                if (!_settings.WallpaperHubPath.Equals(value.WallpaperHubPath))
                {
                    NotifyManager.Instance.Notify("alert", NotifyType.Success, "重启软件后生效");
                }
                SetProperty(ref _settings, value);
            }
        }

        private string? _selectedWallpaper;
        public string? SelectedWallpaper { get => _selectedWallpaper; set => SetProperty(ref _selectedWallpaper, value); }

        private string? _currentWallpaper;
        public string? CurrentWallpaper { get => _currentWallpaper; set => SetProperty(ref _currentWallpaper, value); }

        #region Command

        /// <summary>
        /// 选择壁纸
        /// </summary>
        public ICommand SelectedCommand
        {
            get => new RelayCommand<string>(obj =>
            {
                if (string.IsNullOrEmpty(obj))
                {
                    return;
                }
                SelectedWallpaper = obj;
            });
        }

        /// <summary>
        /// 设置壁纸
        /// </summary>
        public ICommand SetWallpaperCommand
        {
            get => new RelayCommand<string>(obj =>
            {
                if (!string.IsNullOrEmpty(obj))
                {
                    NewWallpaperManager.SetWallpaper(obj);
                }
            });
        }

        /// <summary>
        /// 更新列表
        /// </summary>
        public ICommand UpdateWallpaperListCommand
        {
            get => new RelayCommand<object>(obj =>
            {
                ScanWallpaperCache();
            });
        }

        /// <summary>
        /// 查看图片
        /// </summary>
        public ICommand ViewPictureCommand
        {
            get => new RelayCommand<object>(obj =>
            {
                _windowEvent.Publish(new WindowEvent
                {
                    Data = _selectedWallpaper,
                    WindowActionType = WindowActionType.Open,
                    EventId = EventIds.OpenViewPictureWindow
                });
            });
        }

        /// <summary>
        /// 添加壁纸
        /// </summary>
        public ICommand AddWallpaperCommand
        {
            get => new RelayCommand<object>(obj =>
            {
                Action<object?> upload = (r) =>
                {
                    var files = r as string[];
                    if (files == null)
                    {
                        return;
                    }
                    int errCount = NewWallpaperManager.UploadWallpaper(files);
                    if (errCount > 0)
                    {
                        MessageBox.Show($"失败{errCount}条");
                    }
                };

                _windowEvent.Publish(new WindowEvent()
                {
                    CallBack = upload,
                    WindowActionType = WindowActionType.Open,
                    EventId = EventIds.OpenAddWindow
                });
            });
        }

        /// <summary>
        /// 删除壁纸
        /// </summary>
        public ICommand DeletePictureCommand
        {
            get => new RelayCommand<WallpaperInfo>(fileInfo =>
            {

            });
        }

        /// <summary>
        /// 播放/暂停
        /// </summary>
        public ICommand PlayCommand
        {
            get => new RelayCommand<string>(obj =>
            {
                var isplay = obj == "True" ? true : false;
                if (isplay)
                {
                    ApplyPlay();
                }

                timer.Interval = ConfigManager.Instance.Settings.PlaySetting.Interval * 1000;
                timer.Enabled = isplay;
                IsPlay = isplay;
            });
        }

        /// <summary>
        /// 添加到播放列表
        /// </summary>
        public ICommand AddtoPlaylistCommand
        {
            get => new RelayCommand<string>(obj =>
            {
                if (string.IsNullOrEmpty(obj))
                {
                    return;
                }
                lock (locker)
                {
                    PlayListCollection.Add(obj);
                    NotifyManager.Instance.Notify("alert", DataModel.NotifyType.Success, "添加成功");
                }
            });
        }

        /// <summary>
        /// 打开播放列表
        /// </summary>
        public ICommand ShowPlaylistCommand
        {
            get => new RelayCommand<object>(obj =>
            {
                PlaylistOpen = true;
            });
        }

        /// <summary>
        /// 移出播放列表
        /// </summary>
        public ICommand RemovePlayListCommand
        {
            get => new RelayCommand<string>(obj =>
            {
                if (string.IsNullOrEmpty(obj))
                {
                    return;
                }
                lock (locker)
                {
                    PlayListCollection.Remove(obj);
                }
            });
        }

        /// <summary>
        /// 播放下一张壁纸
        /// </summary>
        public ICommand NextWallpaperCommand
        {
            get => new RelayCommand<object>(obj =>
            {
                NextWallpaper(null, null);
            });
        }

        /// <summary>
        /// 播放上一张壁纸
        /// </summary>
        public ICommand LastWallpaperCommand
        {
            get => new RelayCommand<object>(obj =>
            {
                LastWallpaper(null, null);
            });
        }

        /// <summary>
        /// 在资源管理器中打开壁纸源
        /// </summary>
        public ICommand OpenResourceCommand
        {
            get => new RelayCommand<object>(obj =>
            {
                Process.Start("explorer.exe", Settings.WallpaperHubPath);
            });
        }

        /// <summary>
        /// 在资源管理器中查看壁纸
        /// </summary>
        public ICommand OpenInExportCommand
        {
            get => new RelayCommand<WallpaperInfo>(obj =>
            {
                if (obj == null) return;
                Process.Start("explorer.exe", obj.Dir);
            });
        }

        /// <summary>
        /// 清空播放列表
        /// </summary>
        public ICommand ClearPlaylistCommand
        {
            get => new RelayCommand<object>(obj =>
            {
                PlayListCollection.Clear();
            });
        }

        #endregion

        #region Funs

        /// <summary>
        /// 初始化定时器
        /// </summary>
        private void InitTimer()
        {
            timer.Interval = ConfigManager.Instance.Settings.PlaySetting.Interval * 1000;
            timer.AutoReset = true;
            timer.Elapsed += NextWallpaper;
            timer.Start();
            timer.Enabled = false;
        }

        /// <summary>
        /// 播放下一站壁纸
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void NextWallpaper(object? sender, ElapsedEventArgs? e)
        {
            lock (locker)
            {
                if (PlayListCollection.Count <= 0) return;

                wp_index++;
                wp_index %= PlayListCollection.Count;

                ApplyPlay();
            }
        }

        /// <summary>
        /// 播放上一张壁纸
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void LastWallpaper(object? sender, ElapsedEventArgs? e)
        {
            lock (locker)
            {
                if (PlayListCollection.Count <= 0) return;

                wp_index--;
                wp_index = (wp_index + PlayListCollection.Count) % PlayListCollection.Count;

                ApplyPlay();
            }
        }

        /// <summary>
        /// 应用壁纸
        /// </summary>
        private void ApplyPlay()
        {
            var wallpaper = PlayListCollection[wp_index];
            CurrentWallpaper = wallpaper;
            NewWallpaperManager.SetWallpaper(wallpaper);
        }

        private void RegistSubScriptionToken()
        {
            _subscriptionTokens.Add(_windowEvent.Subscribe(DisposeResource, (p) => p.WindowActionType == WindowActionType.Close && p.EventId == EventIds.Release));
            _subscriptionTokens.Add(_windowEvent.Subscribe(ExecuteLoading, (p) => p.WindowActionType == WindowActionType.Close && p.EventId == EventIds.Release));
            _subscriptionTokens.Add(_windowEvent.Subscribe(LoadingComplete, (p) => p.WindowActionType == WindowActionType.Close && p.EventId == EventIds.Release));
        }

        private void LoadingComplete(WindowEvent @event)
        {
            OnLoading(false, null);
        }

        private void ExecuteLoading(WindowEvent args)
        {
            OnLoading(true, args.ToString());
        }

        private void OnLoading(bool isload, string? message)
        {
            Loading.Message = isload ? message ?? "等待中..." : string.Empty;
            Loading.Visible = isload ? Visibility.Visible : Visibility.Collapsed;
        }

        /// <summary>
        /// 加载壁纸
        /// </summary>
        private void LoadWallpapers()
        {
            PictureCollection.Clear();
            OnLoading(true, "Loading...");

            foreach (var url in ConfigManager.Instance.WallpaperIndex.Wallpapaers)
            {
                string cache = DomainHelper.GetCachedFilePath(url);
                if (File.Exists(cache))
                {
                    PictureCollection.Add(url);
                }
            }

            _windowEvent.Publish(new WindowEvent
            {
                EventId = EventIds.UpdateLayout
            });

            OnLoading(false, null);
        }

        /// <summary>
        /// 扫描壁纸资源
        /// </summary>
        private void ScanWallpaperCache(Project? project = null)
        {
            OnLoading(true, "Loading...");
            NewWallpaperManager.ScanWallpapers(() =>
            {
                Application.Current.Dispatcher.Invoke(() =>
                {
                    LoadWallpapers();
                    OnLoading(false, null);
                    NotifyManager.Instance.Notify("alert", NotifyType.Success, "加载完成");
                });
            });
        }

        /// <summary>
        /// 扫描播放列表
        /// </summary>
        private void ScanPlaylistCache()
        {
            foreach (var url in ConfigManager.Instance.PlayList.Wallpapaers)
            {
                string cache = DomainHelper.GetCachedFilePath(url);
                if (File.Exists(cache))
                {
                    PlayListCollection.Add(url);
                }
            }
        }

        /// <summary>
        /// 保存播放壁纸
        /// </summary>
        private void SavePlayList()
        {
            string[] pl = PlayListCollection.ToArray();
            ConfigManager.Instance.PlayList.Wallpapaers = pl;
        }

        private void UnRegistSubScriptionToken()
        {
            foreach (var item in _subscriptionTokens)
            {
                _windowEvent.UnSubscribe(item);
            }
        }

        private void DisposeResource(WindowEvent @event)
        {
            UnRegistSubScriptionToken();
            SavePlayList();
        }

        #endregion
    }
}
